Skip to content

fix(database-pgsql): normalise jsonb → json in introspector type map#69

Merged
markshust merged 1 commit into
marko-php:developfrom
michalbiarda:fix/pgsql-json-type-normalisation
May 24, 2026
Merged

fix(database-pgsql): normalise jsonb → json in introspector type map#69
markshust merged 1 commit into
marko-php:developfrom
michalbiarda:fix/pgsql-json-type-normalisation

Conversation

@michalbiarda
Copy link
Copy Markdown
Contributor

Summary

  • PgSqlGenerator maps entity type jsonJSONB in DDL (correct — JSONB is preferred in PostgreSQL)
  • PgSqlIntrospector read the column back as jsonb, while the entity schema held json
  • No alias existed in Column::typeEquals() for this pair, so the diff calculator reported a spurious Modify on every json column indefinitely
  • Fixed by mapping 'jsonb' => 'json' in PgSqlIntrospector::TYPE_MAP, normalising the round-trip at the driver level

Closes #68

Steps to reproduce (before fix)

  1. Define an entity with #[Column(type: 'json')]
  2. Run db:migrate — column is created as JSONB in PostgreSQL
  3. Run db:diff — reports Modify column despite no changes

Expected behavior

db:diff reports no changes after the column has been created.

Test plan

  • it normalises jsonb to json so introspected columns match entity-declared type
  • it produces no diff when entity declares json and database stores jsonb

🤖 Generated with Claude Code

PgSqlGenerator maps entity type 'json' to JSONB in DDL, which is correct
(JSONB is preferred in PostgreSQL for indexing and performance). However,
the introspector returned 'jsonb' for those columns, while the entity schema
still held 'json'. With no alias in Column::typeEquals(), the diff calculator
reported a spurious Modify on every json column after the initial migration.

Mapping 'jsonb' → 'json' in PgSqlIntrospector::TYPE_MAP normalises the
round-trip so introspected JSONB columns compare equal to entity-declared
json columns. The fix is intentionally scoped to the PgSQL driver — MySQL
is unaffected (it stores and introspects JSON under the same name).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@markshust
Copy link
Copy Markdown
Collaborator

Thanks @michalbiarda — clean, narrowly-scoped fix. The asymmetry between PgSqlGenerator (writes JSONB) and PgSqlIntrospector (reads jsonb) was the root cause, and normalising at the introspector boundary is the right place to fix it. json is the canonical abstract type across the framework — PostgreSQL just happens to store it as JSONB physically, so the round-trip should be transparent.

I particularly like the end-to-end test (it produces no diff when entity declares json and database stores jsonb) — it exercises the full Introspector → DiffCalculator path that the bug actually affected, which is much stronger coverage than a unit test on the type map alone.

Verified on develop: 131 pgsql tests passing, lint clean. Merging via merge commit to preserve your authorship.

@markshust markshust merged commit e4d1996 into marko-php:develop May 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spurious Modify diff on json columns due to json/jsonb type mismatch

2 participants